/**
 * Play sound in java
 * Taken form: 
 * http://stackoverflow.com/questions/26305/how-can-i-play-sound-in-java
 */
package org.adempiere.apps;

import java.io.File;
import java.io.IOException;
import java.net.URL;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;

import org.compiere.Adempiere;

/**
 * Class Sound play
 * 
 * @author shindu
 * @since 30 July 2013
 * 
 */
public class SoundPlay {

	
	/**
	 * Playing sound
	 * @param filename
	 *        the name of the file that is going to be played
	 */
	public static void playSound(String filename) {

		final int BUFFER_SIZE = 128000;
		File soundFile;
		AudioInputStream audioStream;
		AudioFormat audioFormat;
		SourceDataLine sourceLine;
		
		String strFilename = filename;

		try {
			soundFile = new File(strFilename);
			if (!soundFile.canRead())
			{
				soundFile=null;
				strFilename="";
			}
		} catch (Exception e) {
			soundFile=null;
			strFilename="";
		}

		try {
			if (strFilename.equals("")){
				//Play default beep from resource
				URL url = Adempiere.class.getResource("beep.wav");
				if (url != null)
					audioStream = AudioSystem.getAudioInputStream(url);
				else
					return;
			}else{
				audioStream = AudioSystem.getAudioInputStream(soundFile);
			}
		} catch (Exception e) {
			System.err.println(e.getMessage());
			return;
		}
		//
		audioFormat = audioStream.getFormat();
		//
		DataLine.Info info = new DataLine.Info(SourceDataLine.class,
				audioFormat);
		try {
			sourceLine = (SourceDataLine) AudioSystem.getLine(info);
			sourceLine.open(audioFormat);
		} catch (LineUnavailableException e) {
			System.err.println(e.getMessage());
			return;
		} catch (Exception e) {
			System.err.println(e.getMessage());
			return;
		}
		sourceLine.start();
		int nBytesRead = 0;
		byte[] abData = new byte[BUFFER_SIZE];
		while (nBytesRead != -1) {
			try {
				nBytesRead = audioStream.read(abData, 0, abData.length);
			} catch (IOException e) {
				System.err.println(e.getMessage());
			}
			if (nBytesRead >= 0) {
				@SuppressWarnings("unused")
				int nBytesWritten = sourceLine.write(abData, 0, nBytesRead);
			}
		}
		sourceLine.drain();
		sourceLine.close();
		//menghindari lock file
		try{
            audioStream.close();
        }catch(Exception ex){
            System.err.println(ex.getMessage());
        }
	}
	
	/**
	 * Play beep
	 */
	public static void playBeep(){
		String fileUrl = System.getProperty("user.home") + File.separatorChar + "beep.wav";
		playSound(fileUrl);
	}

	/**
	 * Static function to playSound
	 * 
	 * @param url
	 */
	public static synchronized void playBeepFast() {
		new Thread(new Runnable() {
			// The wrapper thread is unnecessary, unless it blocks on the
			// Clip finishing; see comments.
			public void run() {
				try {
					Clip clip = AudioSystem.getClip();
					AudioInputStream inputStream;
					//
					String fileUrl;
					fileUrl = System.getProperty("user.home") + File.separatorChar +  "beep.wav";
					File file;
					try {
						file = new File(fileUrl);
						inputStream = AudioSystem.getAudioInputStream(file);
					} catch (Exception e) {
						URL url = Adempiere.class.getResource("beep.wav");
						if (url != null)
							inputStream = AudioSystem.getAudioInputStream(url);
						else {
							System.err.println(e.getMessage());
							return;
						}
					}
					clip.open(inputStream);
					clip.start();
				
				} catch (Exception e) {
					System.err.println(e.getMessage());
				}
			}
		}).start();
	}

}
